package com.uinnova.product.eam.service.impl;

import com.binary.jdbc.Page;
import com.uinnova.product.eam.comm.bean.Standard;
import com.uinnova.product.eam.comm.bean.StandardDoc;
import com.uinnova.product.eam.model.StandardCdt;
import com.uinnova.product.eam.service.IEamStandardSvc;
import com.uinnova.product.eam.service.es.IamsEsStandardDocSvc;
import com.uinnova.product.eam.service.es.IamsEsStandardSvc;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.query.CSysUser;
import com.uino.dao.util.ESUtil;
import com.uino.service.sys.microservice.IResourceSvc;
import com.uino.util.rsm.RsmUtils;
import com.uino.util.sys.SysUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 标准规范接口实现类
 *
 * @author uinnova
 * @version 2020-9-23
 */
@Deprecated
@Service
public class IamsEamStandardSvcImpl implements IEamStandardSvc {

    private static final Logger log = LoggerFactory.getLogger(IamsEamStandardSvcImpl.class);

    @Autowired
    private IamsEsStandardSvc iamsEsStandardSvc;

    @Autowired
    private IamsEsStandardDocSvc iamsEsStandardDocSvc;

    @Value("${local.resource.space}")
    private String localPath;

    @Autowired
    private IResourceSvc resourceSvc;

    @Value("${http.resource.space}")
    private String urlPath;

    @Autowired
    private IUserApiSvc userApiSvc;

    @Autowired
    private RsmUtils rsmUtils;

    /**
     * 文档合法性正则
     */
    @Value("${uino.eam.word_name_regex}")
    private String wordNameRegex;

    @Override
    public Long addStandard(Standard standard, MultipartFile[] files) {
        Set<Map<String, Object>> docs = standard.getDocs();

        long standardId = ESUtil.getUUID();
        for (MultipartFile file : files) {
            //保存文件到服务器
            Map<String, Object> map = saveFile(standardId, file);
            docs.add(map);
        }
        standard.setId(standardId);
        return iamsEsStandardSvc.saveOrUpdate(standard);
    }

    @Override
    public void deleteStandardDoc(Long standardId, Long standardDocId) {
        StandardDoc standardDoc = iamsEsStandardDocSvc.getById(standardDocId);
        if (standardDoc != null) {
            if (standardDoc.getRealPath() != null) {
                // 删除服务器文件
                new File(standardDoc.getRealPath()).delete();
                rsmUtils.deleteRsm(standardDoc.getRealPath());
            }
            // 删除标准文档es索引数据
            iamsEsStandardDocSvc.deleteById(standardDocId);
        }
        // 在标准中删除
        Standard standard = iamsEsStandardSvc.getById(standardId);
        Set<Map<String, Object>> docs = standard.getDocs();
        docs.removeIf(doc -> doc.containsValue(standardDocId));
        iamsEsStandardSvc.saveOrUpdate(standard);
    }

    @Override
    public Page<Standard> searchStandards(StandardCdt standardsCdt) {
        if (standardsCdt.getPageSize() == null || standardsCdt.getPageSize() > 20000) {
            standardsCdt.setPageSize(10);
        }
        if (standardsCdt.getPageNum() == null || standardsCdt.getPageNum() < 0) {
            standardsCdt.setPageNum(1);
        }
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
                //must(QueryBuilders.termQuery("ciCode.keyword", standardsCdt.getCiCode()));
        Page<Standard> standardPage;
        if (StringUtils.isBlank(standardsCdt.getSort())) {
            standardsCdt.setSort("createTime");
        }
        if (!standardsCdt.getSort().endsWith("Time")) {
            standardsCdt.setSort(standardsCdt.getSort() + ".keyword");
        }
        standardPage = iamsEsStandardSvc.getSortListByQuery(standardsCdt.getPageNum(),
                standardsCdt.getPageSize(), queryBuilder, standardsCdt.getSort(), standardsCdt.getAsc());
        HashSet<String> loginCodeList = new HashSet<>();
        for (Standard standard : standardPage.getData()) {
            for (Map<String, Object> doc : standard.getDocs()) {
                if(doc.containsKey("operator")){
                    String operator = (String) doc.get("operator");
                    loginCodeList.add(operator);
                }
            }
        }
        CSysUser cSysUser = new CSysUser();
        cSysUser.setLoginCodes(loginCodeList.toArray(new String[0]));
        List<SysUser> sysUserByCdt = userApiSvc.getSysUserByCdt(cSysUser);
        HashMap<String, String> conversionMap = new HashMap<>();
        for (SysUser sysUser : sysUserByCdt) {
            conversionMap.put(sysUser.getLoginCode(), sysUser.getUserName());
        }
        for (Standard standard : standardPage.getData()) {
            Set<Map<String, Object>> docs = standard.getDocs();
            for (Map<String, Object> doc : docs) {
                String operator = String.valueOf(doc.get("operator"));
                doc.put("operator", conversionMap.get(operator));
            }
        }

        return standardPage;
    }

    @Override
    public Standard getById(Long standardId) {
        return iamsEsStandardSvc.getById(standardId);
    }

    @Override
    public StandardDoc getStandardDocByStandardDocId(Long standardDocId) {
        return iamsEsStandardDocSvc.getById(standardDocId);
    }

    @Override
    public Set<Map<String, Object>> uploadStandardDoc(Long standardId, MultipartFile[] files) {
        HashSet<Map<String, Object>> maps = new HashSet<>();
        for (MultipartFile file : files) {
            Map<String, Object> map = saveFile(standardId, file);
            maps.add(map);
        }
        Standard standard = iamsEsStandardSvc.getById(standardId);
        standard.getDocs().addAll(maps);
        iamsEsStandardSvc.saveOrUpdate(standard);
        return standard.getDocs();
    }

    @Override
    public void editStandard(Standard standard) {
        iamsEsStandardSvc.saveOrUpdate(standard);
    }

    @Override

    public void deleteStandardById(Long id) {
        Standard standard = this.getById(id);
        if (standard != null) {
            Set<Map<String, Object>> docs = standard.getDocs();
            //删除标准文档
            for (Map<String, Object> doc : docs) {
                Long standardDocId = (Long) doc.get("standardDocId");
                this.deleteStandardDoc(id, standardDocId);
            }
            //删除标准
            iamsEsStandardSvc.deleteById(id);
        }
    }

    @Override
    public void deleteStandardByIds(Long[] ids) {
        for (Long id : ids) {
            deleteStandardById(id);
        }
    }

    @Override
    public StandardDoc getStandardDocById(Long standardDocId) {
        return iamsEsStandardDocSvc.getById(standardDocId);
    }

    private Map<String, Object> saveFile(Long standardId, MultipartFile file) {
        Map<String, Object> map = new HashMap<>(2);
        Long dateTimeFolder = ESUtil.getNumberDate();
        File destFolder = new File(localPath + "/" + dateTimeFolder);
        if (!destFolder.exists()) {
            destFolder.mkdirs();
        }
        String docName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!(file.getOriginalFilename().matches(wordNameRegex))) {
            throw new RuntimeException(docName + "文件格式不正确");
        }
        //文件名重复删除覆盖
        Standard standard = iamsEsStandardSvc.getById(standardId);
        if (standard != null) {
            Set<Map<String, Object>> docs = standard.getDocs();
            Iterator<Map<String, Object>> iterator = docs.iterator();
            if (iterator.hasNext()) {
                Map<String, Object> doc = iterator.next();
                if (doc.get("docName") == docName && doc.get("docType") == fileType) {
                    long standardDocId = (long) map.get("standardDocId");
                    this.deleteStandardDoc(standardId, standardDocId);
                    iterator.remove();
                }
            }
            iamsEsStandardSvc.saveOrUpdate(standard);
        }
        String destFileName = ESUtil.getUUID() + "." + fileType;
        File destFile = new File(destFolder, destFileName);
        String realpath = null;
        try {
            String wordPath = "/" + dateTimeFolder + "/" + destFileName;
            realpath = destFile.getCanonicalPath();
            file.transferTo(new File(destFile.getCanonicalPath()));
            realpath = destFile.getCanonicalPath();

            File realFile = new File(realpath);
            rsmUtils.uploadRsmFromFile(realFile);

            // 记录资源操作信息
            resourceSvc.saveSyncResourceInfo(wordPath, urlPath + wordPath, false, 0);
        } catch (IOException e) {
            log.error("保存文件异常", e);
        }
        //保存文件到标准文档索引
        StandardDoc standardDoc = new StandardDoc();
        long standardDocId = ESUtil.getUUID();
        standardDoc.setId(standardDocId);
        standardDoc.setName(docName);
        standardDoc.setRealPath(realpath);
        standardDoc.setStandardId(standardId);
        iamsEsStandardDocSvc.saveOrUpdate(standardDoc);
        map.put("docName", docName);
        map.put("standardDocId", standardDocId);
        map.put("docType", fileType);
        map.put("operator", SysUtil.getCurrentUserInfo().getLoginCode());
        return map;
    }
}
